{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [128,128] ; Dense Layers [128,128]\n",
    "### Activation function = Leaky ReLU; Weight initilizer = Xavier\n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[  2.23553\n",
      "X_train             -> array([[[ -1.49427662e-02,  -5.38582681e-03,   3.2\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([1, 4, 1, ..\n",
      "y_train             -> array([1, 5, 7, ..., 4, 3, 3])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.287109375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 1 training accuracy : 0.3896484375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 2 training accuracy : 0.43359375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 3 training accuracy : 0.5595703125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 4 training accuracy : 0.5830078125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 5 training accuracy : 0.6044921875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 6 training accuracy : 0.65234375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 7 training accuracy : 0.654296875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 8 training accuracy : 0.6884765625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Epoch 9 training accuracy : 0.685546875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Training took 30.945867 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 128\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 128\n",
    "ksize_conv2 = 2\n",
    "stride_conv2 = 1\n",
    "\n",
    "pool_layer_maps = 128\n",
    "\n",
    "n_fully_conn1 = 128\n",
    "n_fully_conn2 = 128\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "\n",
    "weight_init = tf.contrib.layers.xavier_initializer()\n",
    "\n",
    "def leaky_relu_activation(inp):\n",
    "    return tf.maximum(0.01*inp, inp)\n",
    "\n",
    "activation_func = leaky_relu_activation\n",
    "\n",
    "# ------------------ Convolutional layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = activation_func)\n",
    "    return convolutional_layer\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, weight_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, weight_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "# ----------------- Pooling layers -------------------------------------\n",
    "\n",
    "def pooling_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "pool_layer_flat = pooling_layer(conv_layer2, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps)\n",
    "\n",
    "# ----------------- Fully connected layers -------------------\n",
    "\n",
    "def dense_layer(input_layer, n_neurons, kernel_init, activation):\n",
    "    fully_conn = tf.layers.dense(inputs = input_layer, units = n_neurons, activation = activation,\n",
    "                                kernel_initializer = kernel_init)\n",
    "    return fully_conn\n",
    "        \n",
    "dense_layer1 = dense_layer(pool_layer_flat, n_fully_conn1, weight_init, activation_func)\n",
    "\n",
    "dense_layer2 = dense_layer(dense_layer1, n_fully_conn2, weight_init, activation_func)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer2, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_leakyrelu_xavier\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.1287499964237213\n",
      "CNN's test accuracy on -18dB SNR samples = 0.12725000083446503\n",
      "CNN's test accuracy on -16dB SNR samples = 0.12925000488758087\n",
      "CNN's test accuracy on -14dB SNR samples = 0.14100000262260437\n",
      "CNN's test accuracy on -12dB SNR samples = 0.1704999953508377\n",
      "CNN's test accuracy on -10dB SNR samples = 0.20624999701976776\n",
      "CNN's test accuracy on -8dB SNR samples = 0.2672500014305115\n",
      "CNN's test accuracy on -6dB SNR samples = 0.37575000524520874\n",
      "CNN's test accuracy on -4dB SNR samples = 0.5\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6397500038146973\n",
      "CNN's test accuracy on 0dB SNR samples = 0.7264999747276306\n",
      "CNN's test accuracy on 2dB SNR samples = 0.7875000238418579\n",
      "CNN's test accuracy on 4dB SNR samples = 0.8149999976158142\n",
      "CNN's test accuracy on 6dB SNR samples = 0.815500020980835\n",
      "CNN's test accuracy on 8dB SNR samples = 0.8119999766349792\n",
      "CNN's test accuracy on 10dB SNR samples = 0.8165000081062317\n",
      "CNN's test accuracy on 12dB SNR samples = 0.8059999942779541\n",
      "CNN's test accuracy on 14dB SNR samples = 0.8034999966621399\n",
      "CNN's test accuracy on 16dB SNR samples = 0.8140000104904175\n",
      "CNN's test accuracy on 18dB SNR samples = 0.797249972820282\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmMAAAGPCAYAAAAQptcZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xl8VOXZ//HPlQ1IWMKOghhccGsVa7XaumBtFbtp1bbS\nUqVW6KLiUhTlwSqWUteKVtsq7sVHW+tWtfVnW0EfW620VRQF45KAbCI7JCSZzFy/P2YCQzKZDCSz\nnfm+X6+8mHPm5HzvM0S5cu5r7jF3R0RERESyoyjbAxAREREpZCrGRERERLJIxZiIiIhIFqkYExER\nEckiFWMiIiIiWaRiTERERCSLVIyJFBAzO9jM/mBm75tZg5mtMbO3Y/tOaXVsJO7rD62e+0Hccz+N\n239Vq++LxHJqzOwuMxuWqWvdGa2uJ2Jmv8j2mESkcKgYEykQZnY0MB84A6gCSoG+wH7A6cCXE3xb\ny0KEp5nZJ5M8n2h/y1cpMBw4B3jJzMp38RLS6TvsOObvZHc4IlJIVIyJFI4pRAujMHAKUAH0Az4D\nXAN8kOR7DZi+k3nT3b0YOBBYGtu3Ryw7Z5jZnsDn4ncBQ81sdHZGlDoz65btMYhI56kYEykc+8b+\n3Az81d0b3H2ju//b3ae7+7XtfF8z0QLlFDMbtbOh7v4O8FjcruHJjjezx2NThc1mNiRuv5nZithz\nH8T2dTezX5jZYjPbbGZbYlOwfzSzI1Ic4neJXh/APXH7x7UzvtPM7LnYFG+jmS0zs0fNrE/cMYPN\n7GYze8fMtprZRjP7j5l9N+6YlinR51udv83+VtO/p5rZ3Wa2Btgae/7zZvZ0bDp4c2xcS83sd2a2\nd4JrON7MnjCzVbFjV5nZn81shJkdEpd1e6vvuyDuuW+l+PqKSAdUjIkUjg9jf1YC75rZb8zsLDOr\n6uD7NgDPsGt3x1pY3OPVHRzbUhAZEP8P/mhgCNFpxHtj+24iesdvX6Ac6EF0CvbrwKdTHNu3Y382\nx861MpZ9eus7T2Z2I/BH4AtEp3hLgN2AU4E+sWP2BhYAFwL7AGVAT2AUcHyr7GTTvO3tnw2Mj+VH\nYvsPB04mWuiWx8Y1lOh06z/MrF/cNVwA/A34GjAwduxA4CRgD3dfALwQO/w7raaVW/4+1rJjgS0i\nnaBiTKRwzCL6j7cDw4AfAPcBH5jZP8zskCTf29Kk/xUzO2xnQs1sf6LFEcAW4KkOvuXPwKrY42/H\n7W957ETHDXBMbPsVogVFBbA/8GNgUQpjOyx2vAPPu/s64PHY072JFiwtxx4OXBI7diPR3rveRAug\ni4H62KG/AgbFjnuMaEHWCzgW2OEuWCecRLToavk7ey52/sFEp6L7AzNjzw0kdpfPzIYCN8T2h4CJ\nRIu63Yj29H0ce25W7M9exPrnYm++OCp2XQ+4e6iLrkWk4KkYEykQ7v4McAIwl+hdoPiG9aOApxI0\n11vse19jexGV6t2xq80sArwN7Am8B3zZ3dd0MM4w8LtY9qfNbC8zKwVOY3vR1HKXryZ23IFEC8Zx\nRAuRe9x9bgpjPCvu8aOt/oQdpyq/Fvf4Jnd/3N3r3H25u9/q7mvMrDvRu2YQLTzPcvcad69393+4\n+5wUxtSRG939b+7e6O5vxfatIFo0vQzUAeuA/4n7nv1if44heqcOYI673+3um9x9tbvf7+4tBeyf\ngPeJvrY/jO0by/Y7nHd3wXWISIyKMZEC4u4vuPsXgAFE3z35W6J3SCA6rXVU62+Je3xV7M+TgSNT\niYv7gugUYln7h+8gvnfr27HMvrHtu+Keuxh4legdqguAO4F/AsvN7AskYWZFwDfjdr1nZgcRnYKr\nI1p4jImb4hscd2x7d936EZ32c2Cpu29NNoYEYypO4bDXW32PEb3j9kNgL6KvcfzrDtHXHna8hrfb\nC3B3J3qHD2BUrP+uZYryX+7e7veKyM5TMSZSIMysV8vj2N2QZ939POD+uMP6tf3Obd/zOvAE0SIl\nYXN7K9OBbkTv2ISJFnuPp7LWWKzp/5XY5tjYF0T7156IO+4Ddz8S2B34ItE+rZVE7479iuROJFqc\neOyangfeJFrsVMSOKQHOjD3+KO57D2jnnOvY/oaH4bE7Ze1piv0Zf8xeHYwZYk37cQ6OjceBt4A9\nY+9iTfSu1VSuocU9wKbY4+uAT8Uy7kxhjCKyE1SMiRSOJ2LvrvuymQ0wsxIz+wTRXqMWHfVZXU30\nH+SU/t/h7s3u/jDQ8q68nkB779ps7R6iRc3+RNdBc+BBd28pYjCzyWb2TaJ3fl4C/kB0ys7o4F2b\nRN9FuW2o7XzB9sLzTy2xwCVm9nUzqzCz3c3sfDMb4O4NwF/jrvWB2DsUy83sM/HvpgSWxM71STPb\nIzYVOyOF16W15rjHjUB9bLmOqQmOfZZoEWjAd83sHDPrY2YDzey7ZratQHP3LWz/OzgutnsL0ddY\nRLqQijGRwlFG9C7VU0Tf0dgEvEG0n8iBJ9x9YavviX8XJO7+JtGeKmPn/IzoXRYDzjSzg1P4noeJ\nNsUb0TtUsP1dlC1Oih33AdBA9K7YYUSv59n2TmxmFWy/c9QIVLp7cfwXsDyW/Rkz29vd5xN996YT\nfefko0SXCVkG3EK0oR5gEtvfgHAG0d6rLUT7ueLfTflg7M+K2DEbgC+1DLHdV6WtxWwvog8D1hDt\npWu5y7ntXO6+HLiU6Bs5SohO+a4nesfsPqLN/vFuZfubPhx4yN3rEZEupWJMpHBMI/ouuflE7x41\nEe2Neg24gu3TcS1a3yFqcTXRaceUl2Vw97XAjWyfEuzw44Zid2b+GDeGBbE3EsS7j+iyGx8Snb5r\nAt4lWjSdRftOI3o3zYEn3X1zgmPm0OrumLtfSvQu3d+ITkk2ES3aHif6Dkvc/X2iy1jcAlQTLRI3\nA/8l+uaJFtcCv4x9fyPR5SQ+R/uve6J9LW94+CrwF6IF78dE/54nJTqXu/+K6Bs5WoryENFi7Fm2\nL3/Scmwt8CTbC7r4fj0R6SIW7dMUERHZUewNBXOBo4H/uPvhWR6SSCCVdHyIiIgUGjNbTPSNEP2J\n3lm7OqsDEgkw3RkTEZE2zCxMtF9sKXCtu8/O8pBEAkvFmIiIiEgWqYFfREREJIvytmfMzHRLT0RE\nRPKGuydctiav74y5e8a+rrrqKuUpL+eylKc85RVOXpCvrRDyksnrYiyTamtrlae8nMtSnvKUVzh5\nQb62QshLRsWYiIiISBYVX3311dkewy6ZPn361Zkce2VlJVVVVcpTXk5lKU95yiucvCBfWyHkTZ8+\nnauvvnp6oufydmkLM/N8HbuIiIgUFjPDg9jAn0nz5s1TnvJyLkt5ylNe4eQF+doKIS8ZFWMiIiIi\nWaRpShEREZE00zSliIiISI5SMZaioM9lKy8/s5SnPOUVTl6Qr60Q8pJRMSYiIiKSReoZExEREUkz\n9YyJiIiI5CgVYykK+ly28vIzS3nKU17h5AX52gohLxkVYyIiIiJZpJ4xERERkTRTz5iIiIhIjlIx\nlqKgz2UrLz+zlKc85RVOXpCvrRDyklExJiIiIpJF6hkTERERSTP1jImIiIjkKBVjKQr6XLby8jNL\necpTXuHkBfnaCiEvGRVjIiIiIlmknjERERGRNFPPmIiIiEiOUjGWoqDPZSsvP7OUpzzlFU5ekK+t\nEPKSUTEmIiIikkXqGRMRERFJs5zqGTOzMWa22MyqzWxKgueHm9nfzGyBmT1vZrtneowiIiIimZLR\nYszMioDbgJOAg4CxZrZ/q8NuBO5z90OAa4BrMznG9gR9Llt5+ZmlPOUpr3DygnxthZCXTKbvjB0B\nvOvuS9w9BDwMnNLqmAOB5wHcfV6C50VEREQCI6M9Y2Z2OnCSu0+MbY8DjnD3SXHHzAH+5e6/MrPT\ngEeAAe6+vtW51DMmIiIieSFZz1hJpseSYF/riupS4DYzGw+8CCwHmhOdbPz48VRVVQFQWVnJqFGj\nGD16NLD99qO2ta1tbWtb29rWdqa3Wx7X1tbSIXfP2BdwJPBs3PblwJQkx1cAS9t5zjNp7ty5ylNe\nzmUpT3nKK5y8IF9bIeTF6paE9U5Rx+Val5oP7GNme5pZGXAm8Kf4A8ysv5m13EG7Argnw2MUERER\nyZiMrzNmZmOAW4i+eeBud7/WzKYD89396Vhf2S+ACNFpyvM82uzf+jye6bGLiIiI7IpkPWNa9FVE\nREQkzXJq0dd8Fd+Qpzzl5UqW8pSnvMLJC/K1FUJeMirGRERERLJI05QiIiIiaaZpShEREZEcpWIs\nRUGfy1ZefmYpT3nKK5y8IF9bIeQlo2JMREREJIvUMyYiIiKSZuoZExEREclRKsZSFPS5bOXlZ5by\nlKe8wskL8rUVQl4yKsZEREREskg9YyIiIiJppp4xERERkRylYixFQZ/LVl5+ZilPecornLwgX1sh\n5CWjYkxEREQki9QzJiIiIpJm6hkTERERyVEqxlIU9Lls5eVnlvKUp7zCyQvytRVCXjIqxkRERESy\nSD1jIiIiImmmnjERERGRHKViLEVBn8tWXn5mKU95ystOXk1NLRPOm8bRXxjLhPOmUVNTm/bMoL6W\nhZKXjIoxEZEC0FI8TJtxR0aKh0znZVJNTS1jJ15PddM46ipOpbppHGMnXh+oa8ykIP+spEo9YyIi\nAddSPHSrmkRxaTnhUD1bP7iVO2f9hL33HkGv8ra/lzc2RVizMQwOEQcHPALdyowh/UvaHF/fEGHp\nqhAOfPhhLZdfOYte+164La+x9lYeuvMyRoyoSts1zrzxLtZsCDGgspSpk8/d5axQs1PfEKGuwSku\ngsH9drzeCedNo7ppHMWl5dv2hUP1VNnvuO+OGZglbAuSBBL9bKb7ZyVbkvWMqRgTEQm49oqHpa/f\nySljpzDrksFtvuf16gYumbW6zf6D9+nW4fE182cxfNTENnkjy+Yw+/YZACyqbWTabz+me6nRvVsR\n3cuMbmXGyOFl/PC0vm3Ov2ZDM/98Y+u2Y7uXGd27GZU9iwlvXZ6w2PyfKybRt/9w6hsi1Dc4dQ0R\nhvQr4YufqWhz/lff2sq196+lriFCqHn7/s8d0oOf/WDgDsd+/TtT2NjnvDbnqHn1l4w9Zyozfzyo\nzXNbGyI0NTu9K4pUrMVp72dzT37HA7N/nsWRdb1kxVjbX2/SP5gxwCyiU6R3u/t1rZ7fA7gfqIwd\nc4W7/yXT42xt3rx5jB49WnnKy6ks5SkvFWs2hCjuE/3Hbv3yl+k79CiKS8spLopQ0SNxt0q3MmO3\n/sVYkWGAWfRrUL/ihMeXdy9i5PAyzOCjN3zbP67xeWs2hLYdX7c1wvpNkdhWeNv+9uqUpauamfXw\n+jb7R+3bjc3v3bWtEGvJ67HXJC664k5GHH7RDscffmD3hMVYURFs2BIdT3ERVPQoory70aei7esz\noLKUdU31O+SFQ/WUlBQxoDLxP6v/eGMrM+9bS3l3Y0i/Egb3L2FI/2I+tV93PndIecLvadFy12/R\nO+9zwH57d+qu387ozM/m6nXNLP+4mVXrmlm1pplVa5tZtS7MBd/oyz57lG07rr2fzf97tY4zLl/G\njB8OZP+qbl1xOW1k+r/1ZDJajJlZEXAbcAKwAphvZk+6++K4w6YBv3f3O8zsAODPwIhMjlNEJN/U\nbY3w8ptb+c/iBi4d14+iou1VTXzx0CIcquf4T/fk5z8amOh0HFDVjQd/NjTl/JHDy/jt5UMAmLC0\nguoEeQMqS7dtH7Jvd/74i6FsbYrQ0Og0NEW/yrslrsb69i7iK0f3pKExwtYmpzF2/IihpTz/7+3/\noLcoLi2nZw/nc4f0oKJ7tLCq6F7E8CGlCc9/8D7defS6oZR3M8pKLendq6mTz912J67l2hprb+W5\nhy5jj+Ft7+oBbG2MUN7dqG9wPlgR4oMV0cLUIGEx9p/FDbz85laKQ8u447e/ps9+F1JXsYDqpkMY\nO/H6jEz5LnrnfQ545G9tir9w2Pl4Q5iP1jazx+BS+vVpW6D/8n/X8erbDW32L1sd2qEYa+9ns6Sk\niHWbIgzqm7hMefqlLQzoU8zIPcvo1zvxLwj5JKPTlGZ2JHCVu58c274c8Pi7Y2b2G+ADd7/BzI4C\nbnD3oxOcS9OUIlLQttRH+Ocb9bzw2lb+vWjrtum1W38ymE/svf1uQqb7cjKd195UV/y0aFfblR41\nd2dzfYRVa8PRO0Vrm9l3jzIO3a97m2PveWoDc/6yKaUpX4DH5m7mLy9voazEKC2JFpRlpcYXj6jg\nuE+1LfYWVDeweEnTtuPKYt9TEl7OT6be3Obv7nvf/zHvrBrIR2ubWb0+TDh2U/Pys/px4pE9E45/\nQXUjg/sXM6R/Cbv1j94N3GdYKb0rthdP7f2sPPjbS+nRZw92H9C2GAs1O1+55MNtP+8DKovZb3gZ\nI4eX8a0v9qasNDengXOmZ8zMTgdOcveJse1xwBHuPinumCHAc0BfoBz4gru/luBcKsZEpKBdfPNH\nLHi3EYhO731y724c96lyjj+snMpeO94t6MoG91RkMi+ITeCLaht5491GbrhuOr1HXtjm+T4bb+fx\nB7d3+fz2sfX84W+b2xw38dRKzjyxd5v9dzy2nt8nOL545e00Dfhem+KPlfdQPPz8bfv69ylmSP9i\nvnFCb449NPk0a0d29mdly9YIv/vzRqqXNvHuh03UN0Rrgd4VRTx+/dA2dzUjEWdjXYS+sf8mMv3f\nQotcKsbOAE5sVYwd7u4Xxh1zMYC73xy7k3a3ux+U4FwZLcaC2EeivPzPUl5h5Ll7wmmzx+Zu5qXX\n6znuU+UcM6o84XTRruR1pUzl5WNfVSri7/rF96e1vjO2dmOYdZvChJqdplD0K9TsDB9Syh6D207N\nvvzmVl6vbth2XFPIaWp2Xnz6ehh6AbC9hwug2+rbuOaa6QzpX8LgfiVpufu0K69lJOIs+7iZ6iVN\n1DVEOOXYXm2OWboqxPhrVjKobzEDy1fx/DOzGXDQRWxavYDegw7JWOGeSw38y4DhcdvDiPaOxfs+\ncBKAu79iZt3NbIC7r2l9svHjx1NVVQVAZWUlo0aN2vYX2bKYW1dtv/766116PuUFO0/b2u7s9pb6\nMPT+DC++Vk/jun/x9eN6tTn+tONHc9rxvZg3bx5vvJZb48/G9uzbZ2x7vGRJ7bZ/XHNlfLuyPXXy\nuXz5jAspHXI6RSXdCIfq+fi/U/jh5LG02NXz/+j0ts9PeL0br9bOo6hk+zT32iXzGFa6ksMP7JHW\n692V6ykqMj5Y9A9KgFPaOf7Pzz5P3eqNrOZI/vXcg/Qe9Fk2rV4ARHsLt5YdyfkXX8kzT/yuy69n\n3rx51NbW0pFM3xkrBt4h2sC/EngVGOvui+KOeQb4g7vfH2vg/6u7D0twLk1TikjeSjRVMmjIcP4+\nv44XX6vn9XcbicT6cgb1LeahGbtrSYQCpSnfzgtHnGUfNXPWhCsoHj6pzfOtp33TIWemKWODGQPc\nwvalLa41s+nAfHd/OlaAzQZ6AhHgUnf/e4LzqBgTkbzU3j94v7npJ0y+oxT36PIKhx3QneMOLeez\nB/egT8/8f8eY5Ids9VRlQjbe7NEipz4o3N2fdff93H1fd782tu8qd3869niRux/t7qPc/VOJCrFs\naH0bVXnKy4Us5eVn3swbd1wXq7i0nG5Vk/j1Hfdy5hd7M+Wsfjx2/TCuPW8QJ3+2Z5cWYkF8PQsl\nL1NZI0ZUMfv2GVw44WRm3z4jY4VYJq5v6uRzaay9lXConvXLX972i9DUyeemPTuZjBdjIiKF7v1l\njTv8Zg5sWxR1wqmVnHRkz4QfUSQinTNiRBUP3XkZI8vmUFH3BCPL5uTEFKw+DklEJEOaQs5dT27g\nhut+ltLaUSISHDk1TSkiUoiWrw4x6aaP+OPzm9n9gDNY+/as6PpNkDNTJSKSHSrGUhTkPgTl5W+W\n8vIj7+/z65j4i1VUL21iSP9i7pp+GE/NuZyRZXNoqp6S0amSILyehZoX5GsrhLxkMv5B4SIihWbj\nlghbG53Rnyrnkm/3o2d5EVC1bV2slvWJRKQwqWdMRCTN3J1X327giAO7a60wkQKVU+uMdRUVYyIi\nIpIv1MDfBYI+l628/MxSXm7lbdwSZsG7DRnL2xXKy9+8IF9bIeQlo2JMRKQLLKhuYMLMVUz7zces\nXNOc7eGISB7RNKWISCeEw87v/rKROX/ZRMThoL3KmHbOAAb30/ujRGS7ZNOU+r+FiMguWr2umZ/f\nt5Y332vEDL4zpjfjv9yH4mI16YtI6jRNmaKgz2UrLz+zlJfdvPWbwyyqaaR/n2JumDSI73+tcqcL\nsVy+PuXlVl6Qr60Q8pLRnTERkV20357duOrcARy0Vzcqe3Xdh3mLSGFRz5iIiIhImmlpCxGRTnB3\nFr7fmO1hiEhAqRhLUdDnspWXn1nKS39e3dYIP793LZNu+ogXX6tPe166KS9/84J8bYWQl4x6xkRE\n2rG4tpEZ965lxcfNdO9mhJrVGiEiXU89YyIirUQizh+f38zsJzYQjsA+w0q58vsD2GNwabaHJiJ5\nSuuMiYh0oKamlpk33sWaDSEqe5WwrvSrhCO7c9ronkz8el/KSrV2mIikh3rGUhT0uWzl5WeW8rpG\nTU0tYydeT3XTOGq3fIoPwt/lwzfv50dfreP8b/ZLayEWxNdTefmfpbzMUjEmIgVv5o130a1qEsWl\n5QAUl5bTa98Lee7pB7M8MhEpBOoZE5GC9/XvTGFjn/Pa7O+z8XYef/C6LIxIRIJG64yJiLTjrQ8a\n2VQH4dCOy1aEQ/UMqFTDvoikn4qxFAV9Llt5+ZmlvM6pXtrE5bevZmuvU9iweBbhUD3rl79MOFRP\nY+2tTJ18btqyWwTp9VRecLKUl1kqxkSkINWsaOKyX62mbqtz4rH78ui9UxhZNoeKuicYWTaHh+68\njBEjqrI8ShEpBBnvGTOzMcAsooXg3e5+XavnfwkcDzhQAQx0934JzqOeMRHZJR9+FOKimz9i/aYI\nR36iO9MnDqS0REtXiEj65Mw6Y2ZWBNwGnACsAOab2ZPuvrjlGHe/JO7484FRmRyjiATfzQ+tY/2m\nCIft352rJ6gQE5HsyvQ05RHAu+6+xN1DwMPAKUmOHws8lJGRdSDoc9nKy88s5e2aqeP7c/JRFVzz\ngwFt1hALwvUpL5h5Qb62QshLJtPF2FDgw7jtZbF9bZjZcKAKeD79wxKRQjKgsoRLv9ufHt3UNisi\n2ZfRnjEzOwM40d0nxrbHAYe7+4UJjr0MGJroudjzfvbZZ1NVVQVAZWUlo0aNYvTo0cD2ilfb2ta2\ntrWtbW1rO9PbLY9ra2sBuP/++9vtGct0MXYkcLW7j4ltXw546yb+2HP/BX7s7q+0cy418ItIhxqa\nInQrNczUFyYi2ZNLi77OB/Yxsz3NrAw4E/hT64PMbD+gsr1CLBviK13lKS9XspSX3NaGCJNvWc3t\nj6wnEkntl7d8uj7lFVZekK+tEPKSyWgx5u5h4HzgOeAt4GF3X2Rm083sK3GHnkm0uV9EZJc0NkX4\nn99+zNs1Tby0YCub6iLZHpKISEL6bEoRCZymkPPTOz7m1bcb6N+nmFkXD2LoIH20kYhkTy5NU4qI\npFVz2JlxzxpefbuByp5F3DhJhZiI5DYVYykK+ly28vIzS3lt1W2N8OHqZnr2MG6YNIg9d9u5QizX\nr095hZsX5GsrhLxkMroCv4hIuvXpWczNFw3i4w1h9h5Wlu3hiIh0SD1jIiIiImmmnjERERGRHKVi\nLEVBn8tWXn5mKQ9eWbg15TXEuiKvqylPebmYpbzMUjEmInnroec2MfXXHzPr4fXZHoqIyC5Tz5iI\n5KXH5m7mtkfWYwaXn9WfL36mIttDEhFpl3rGRCRQnvnHFm57JHo37OKx/VSIiUheUzGWoqDPZSsv\nP7MKMe8fC+r55f+uA+C8Myr5ytE905qXbspTXi5mKS+ztM6YiOSVT+zdjb2HlTL60HJO/3zvbA9H\nRKTT1DMmInmnKeSUlSZsvRARyUnqGRORQFEhJiJBomIsRUGfy1ZefmYFOa+mppYJ503j6C+MZcJ5\n06ipqc1IblBfT+Xlf16Qr60Q8pJJqRgzs/3TPRARkRY1NbWMnXg91U3jqKs4leqmcYydeH3GCjIR\nkUxKqWfMzCLAy8BdwB/cvS7dA+uIesZEgmvCedOobhpHcWn5tn3hUD0jy+Yw+/YZWRyZiMiu6Yqe\nsYOBV4HrgJVmdpeZHdVVAxQRibdmQ2iHQgyguLScNRtCWRqRiEj6pFSMuftCd78Y2B34HjAEeNHM\n3jazn5jZoHQOMhcEfS5befmZFdS88u7FhEP1AKxf/jIQvTM2oLI07dlBfD2VF4y8IF9bIeQls1MN\n/O7e7O6PAl8HJgN7ATcAS83sPjMbnIYxikgBcXd6Dj+Nmvm/3FaQhUP1NNbeytTJ52Z5dCIiXW+n\n1hkzs4OBc4DvACHgAeBuonfMrgZ6uPuRXT/MhGNRz5hIAG1tjHDNXWt49bX3GFb0DJvqmhlQWcrU\nyecyYkRVlkcnIrJrkvWMpdrA/2OiRdghwF+JNvL/yd2b447ZA6hx94ys6q9iTCS43J3V68MM7qcP\nCRGRYOiKBv7LgaeBvdz9S+7+WHwhFrMaOK8T48xpQZ/LVl5+ZgU1z8y2FWJBvD7lKS/Xs5SXWan+\n2rlnR7eh3L0RuKPzQxIREREpHKlOU04ENrv7Q632jwV6uvvsNI0v2Zg0TSkiIiJ5oSumKScDqxLs\nXx57bmcGM8bMFptZtZlNaeeYb5rZW2b2ppnN2Znzi0j+WVTTyIo1rTsfREQKQ6rF2HCgJsH+pbHn\nUmJmRcBtwEnAQcDY1h+1ZGb7AFOAo9z9k8BFqZ4/nYI+l628/MwKQl5TyJlx71q+d80K3vqgMe15\nHVGe8nI1L8jXVgh5yaRajK0GPplg/yHA2p3IOwJ4192XuHsIeBg4pdUxE4Db3X0TgLuv2Ynzi0ie\n+f3fNrFyTTNDB5ay355l2R6OiEjGpdozdj3wDeAs4KXY7mOA+4HH3P0nKYWZnQ6c5O4TY9vjgCPc\nfVLcMY91v2dAAAAgAElEQVQD1cDniBaL0939/yU4l3rGRPLcqrXNfO+alTSGnF9eNIhRI7tne0gi\nImmRrGcs1XdTXgnsC7wANMX2lQJPAVN3ZiwJ9rWuqEqAfYBjiU6B/p+ZHdRyp0xEguM3j66nMeQc\n/+lyFWIiUrBSKsZiy1Z83cw+CYwiWlT9190X7mTeMnbsMRsGrEhwzMvuHgFqzewdooXgf1qfbPz4\n8VRVVQFQWVnJqFGjGD16NLB9LrirtmfNmpXW8ysvOHnxfQjKa3977cYwryzcl+7djE8OWsC8ecWB\nuj7lKa+rt1tnKi+381oe19bW0iF3z9gXUAy8B+wJlAGvAwe0OuYk4L7Y4wHAEqBvgnN5Js2dO1d5\nysu5rHzPW7a6yV98rS5jealQnvJyNS/I11YIebG6JWF9lPJnU5pZFXAa0TtbZa0Kuh+ndJLoecYA\ntxDtB7vb3a81s+nAfHd/OnbMTcAYoBmY4e6PJDiPpzp2ERERkWzqis+m/CLwJ2Ax0SUpFgB7Eb3T\n9aq7n9h1w02NijERERHJF12x6OtM4Fp3PxRoBL5F9A7ZC0SLtMCLnwNWnvJyJUt5ylNe4eQF+doK\nIS+ZVIux/YGWlfCbgR7uXgf8FLg0HQMTkeDZVBfO9hBERHJOqtOUq4Dj3X2Rmb0NXO7ufzKzg4F/\nunvPdA80wZg0TSmSR5rDzoSZq9itfzGXfrc/fXsVZ3tIIiIZ0xXrjL0KfBZYBDwL3GBmBwCnx54T\nEUnqsbmbWbIyRHOzU9E91ZvyIiLBl+r/ES8lugwFwFXAP4HvE/2YpO+nYVw5J+hz2crLz6x8yVuz\noZn7n9kIwPnf7EtZacJfDrssrzOUp7xczQvytRVCXjId3hkzsxJgKPAagLtvBr6X5nGJSIDc+fgG\ntjY6nz24B585qEe2hyMiklNS7RlrILo4a036h5Qa9YyJ5Ic332vgwl+upqzUuPfK3dhtQKrdESIi\nwdEVPWMLgRFAzhRjIpIfRg4vY/xX+lBaYirEREQSSLVnbCrRpv0xZjbQzMrjv9I5wFwR9Lls5eVn\nVj7kdSsr4qwv9WHsib0zktdZylNeruYF+doKIS+ZVH9NfTb255+BRHODeo+6iIiIyC5ItWfspGTP\nu/v/67IRpUg9YyIiIpIvOv3ZlLlIxZiIiIjki05/NqWZHZjsq2uHm5uCPpetvPzMysW8cMT56R0f\n848F9XTFL0y5dn3KU1628oJ8bYWQl8zOvJvSgZaKrvX/YdUzJiIAPP3SFl5asJXqpU0cfmAPykqz\nPSIRkdyWas/Yfq12lQKHAlOAK9z9qTSMraMxaZpSJMds3BLmrKtXsrk+wtUTBnDsoQXxZmsRkQ51\nep0xd38nwe6FZrYGuALIeDEmIrnnric3sLk+wmH7d+eYUVppX0QkFZ39tN53gcO6YiC5Luhz2crL\nz6xcyltc28if/1lHSTFc8M2+mKX++ZO7kpcuylNeruYF+doKIS+ZlO6MJVjY1YDdgGuA97p6UCKS\nfxpDzpD+JRx3aA+GD1GjmIhIqlLtGYuQeLHXj4Bvufv/dfXAOqKeMZHc0xRyIu50L+vsTXcRkWDp\nis+m/BI7FmMR4GPgbXdv6uT4RCQgykqN7W+6FhGRVKT066u7P+vu/y/u66/u/nohFWJBn8tWXn5m\nKU95yiucvCBfWyHkJZPqoq8TzWxsgv1jzWxC1w9LREREpDCk2jNWDfzA3ee22n8sMNvdW69Dlnbq\nGRPJrkjEeeqlLZx0ZIV6xEREOtDpj0MChgM1CfYvjT0nIgXmuX/VccvD6/nJrNVd8rFHIiKFKtVi\nbDXwyQT7DwHWdt1wclfQ57KVl59Z2crbUh/hzsc3AHDqcb26bE2x9vIySXnKy9W8IF9bIeQlk2ox\n9jBwq5kdY9sdC8wCfr8zgWY2xswWm1m1mU1J8PzZZrbazP4b+zpnZ84vIul339Mb2LAlwif37sYX\njtBHHomIdEaqPWPdiBZkpwAt76AsJfoxSN9y98aUwsyKgGrgBGAFMB84090Xxx1zNnCYu0/q4Fzq\nGRPJoJqaWmbeeBcfrmqiemkzQ/Y/g9/94tPsPaws20MTEcl5XfHZlI3A183sE0Q/INyA/7r7wp0c\nyxHAu+6+JDawlgJvcavjtFCRSA6pqall7MTr6VY1ieLB5ezRr57VC2dRFNodqMr28ERE8lqqS1sU\nmVmxuy9099+5+wPuvtDMimN3u1I1FPgwbntZbF9rp5nZ62b2BzMbthPnT5ugz2UrLz+zMpU388a7\nooVYaTnrl79McWk5gz5xETNvvCvt2UF8PZWnvFzPUl5mpboC/x+Bl4EbWu2/CPgscHqK50l0x6v1\nXOOfgP9195CZ/QC4n+i0Zhvjx4+nqqoKgMrKSkaNGsXo0aOB7S9yV22//vrrXXo+5QU7L2jbi955\nn7qKBfQdehQA65e/DMCanqGcGJ+2tV0I2y2Ulx95LY9ra2vpSKo9Yx8Dn3f3N1vt/wTwd3cf3OFJ\noscfCVzt7mNi25cD7u7XtXN8EbDO3SsTPKeeMZEMmXDeNKqbxlFcur1ZPxyqZ2TZHGbfPiOLIxMR\nyQ9dsc5YT7Y37sdrBnrvxFjmA/uY2Z5mVgacSfROWPxgh8RtngK8vRPnF5E0mDr5XBprbyUcqgei\nhVhj7a1MnXxulkcmIpL/Ui3GFgLfTLD/m+xEseTuYeB84DngLeBhd19kZtPN7CuxwyaZ2UIzey12\n7PhUz59OrW9rKk95uZCVibx1m8J42e48dOdljCybQ1P1FEaWzeGhOy9jxIiqtGZD8F5P5SkvH7KU\nl1mp9ozNAP5oZlXA87F9JwDjgG/tTKC7Pwvs12rfVXGPpwJTd+acIpIe7s6sh9bxysKtXHH2QGbf\nPoN58+Zt640QEZHOS6lnDMDMTgWmEV11H2AB8HN3fzxNY+toPOoZE0mzv8+v4+f3rqW8u3H3tN0Y\n3C/V399ERCRep9cZA3D3J4AnumxUIpLT1m4Mc+vv1wPw49P7qhATEUmTVHvGCl7Q57KVl59Z6cpz\nd375v+vYXB/hiAO7c/JnK9Kal4zylKe8zGcpL7NSKsbMrMTMrjCzN8xsg5nVx3+le5Aiklkr1jTz\nenUDFT2Mn3ynX1o/CFxEpNClus7YDKLvarwBuBa4BhgBnEZ03bDb0jjG9saknjGRNFq1tpkPPwpx\n+IE9sj0UEZG8l6xnLNVi7APgAnd/xsw2A6Pc/X0zmwR81t3P7Nohd0zFmIiIiOSLrlj0dQjQsvr+\nFqBP7PHTwMmdG15+CPpctvLyM0t5ylNe4eQF+doKIS+ZVIuxZUQLMoAP2P5ZkYcBjV09KBEREZFC\nkeo05U3ABnf/mZmNBR4A3iPaN/Yrd780vcNMOCZNU4p0EXfnlYUNHPmJ7mrWFxFJg073jCU44XHA\n54Bqd/9jJ8e3S1SMiXSdZ/6xhZseXMfxny7nynMGZHs4IiKB0xU9Yztw9xfcfWa2CrFsCPpctvLy\nM6sr8j5a18xvHo0u7vrZT3b8zsl8uz7lKS8oeUG+tkLIS0aLvooUMHfnxjnrqG9wjj6kB5//dHm2\nhyQiUnB2aZoyF2iaUqTznvq/zdz80Hp6VxRxz5W70a93cbaHJCISSF0+TSki+c/def7f0Q/QuOjM\nvirERESyRMVYioI+l628/MzqTJ6ZccOkQfz0+/0ZfVhFx9/QybxdpTzlKS/zWcrLrFQ/m/LPZtYn\nwf5eZvbnrh+WiGRCSbHtVCEmIiJdL9V1xsLAbu6+utX+gcAKdy9N0/iSjUk9YyIiIpIXkvWMlXTw\njQe2PARGmln8AkTFwBhgRZeMUkRERKQAdTRNuZDoZ1I68ELsccvXAuBnwC/SOcBcEfS5bOXlZ9bO\n5s1/eyub6sIZy+sKylOe8jKfpbzMSnpnDDiA6F2xt4FjgDVxzzUBK929IU1jE5EutHx1iKvuXEN5\nd2P2/+xG315696SISC5ItWesm7vn1AeCq2dMJHWRiHPxzat58/1GTji8nP/5nj7ySEQkk7pinbGT\nzezzcSe8zMzeM7MnY038IpLDHpu3mTffb6Rf7yLO/0bfbA9HRETipFqMzQDKAMzsEKK9Yg8A/YCb\n0jO03BL0uWzl5WdWKnkffhTi7ic3AnDxt/vRp2fnpidz7fqUp7xCyQvytRVCXjId9Yy1qAIWxx6f\nBjzp7teY2dOA1hkTyWH/XtRAY8g58TMVfO5gffakiEiuSbVnbB1wtLu/bWYvAQ+4+51mVgW87e4p\n/x/ezMYAs4jelbvb3a9r57gzgD8An3b3/yZ4Xj1jIilaUN3AXsPK6FWuD90QEcmGXV5nLM4/gOvM\n7EXgCODM2P59geU7MZAi4DbgBKLrk803syfdfXGr43oCFwCvpHpuEWnfISO7Z3sIIiLSjlR/Tb4A\n6A6cC1zo7sti+78G/H0n8o4A3nX3Je4eAh4GTklw3M+A64CceQdn0OeylZefWcpTnvIKJy/I11YI\necmkdGfM3WuBLybYf8FO5g0FPozbXka0QNvGzEYBw9z9z2Z26U6eX0RERCSvpNQzBmBmpcBJwN7A\nve6+ycz2ADa6+6YUz3EGcKK7T4xtjwMOd/cLY9sGPA+c7e5LzWwuMNnd/5PgXOoZE0lgycoQm+sj\nfGLvbtkeioiIxHS6ZyzWqP9XYDBQDjwFbAJ+AvQAfpDiWJYBw+O2h7HjZ1v2Ag4C5sUKsyHAk2b2\ntURN/OPHj6eqqgqAyspKRo0axejRo4Httx+1re1C2j7mmOO49oG1/OvlFzjrS324aOKYnBqftrWt\nbW0XynbL49raWjrk7h1+AU8C9wGlwGZgr9j+44D3UjlH7Phi4D1gT6Lrlr0OHJDk+LnAoe0855k0\nd+5c5Skv57Ja5z34lw1+/I+W+LemLvMt9eG052WC8pSnvMxnKa/rxeqWhPVOqu+m/BzwOXcPRW9Y\nbbME2D3Fc+DuYTM7H3iO7UtbLDKz6cB8d3+69bcQ/WxMEelAzYom7v9zdHHXyeP6UdGjKMsjEhGR\nVKS6zth6osXY22a2GTjE3T8ws6OBR919cLoHmmBMnsrYRQpBc9g5/4aPqF7axFeP7snF3+6X7SGJ\niEicrvhsyr8SXd6ihZtZBXAV8GwnxycinbRsdTMfrWtmcL9ifnBaZbaHIyIiOyHVYmwycJKZvUF0\nvbEHgA+AEcCUNI0tp8Q35ClPebmQVVNTy4TzpnH0F8by8xnTueq7jVzzg4GUd0/v9GSQ/+6Up7xc\nzgvytRVCXjIp/V/b3ZcCBwO/Ae4H3iW6MOuh7r4qfcMTkURqamoZO/F6qpvGUVdxKtVN4/jhJTdR\n0rwi20MTEZGdlLRnzMzuIbri/ubMDSk16hmTQjbhvGlUN42juHT7x8KGQ/WMLJvD7NtnZHFkIiKS\nSGd6xs4muo6YiOSQNRtCOxRiAMWl5azZEMrSiEREZFd1VIxpWYmYoM9lKy+/snr2KCEcqgdg/fKX\ngeidsQGVpWnPDvLfnfKUl8t5Qb62QshLJpWeMc0FiuSQppDjA06lZv4vtxVk4VA9jbW3MnXyuVke\nnYiI7KyOesYipFCMuXtxVw4qFeoZk0J1y+/X8eQLW6goWkH/0FNs3NLMgMpSpk4+lxEjqrI8OhER\nSaSzn005EdjQtUMSkV3x9/l1PPnCFkpL4IZLDmX/qiOzPSQREemkVKYpn3L3R5N9pX2UOSDoc9nK\ny/2sJStD3PS/6wD48Rl92b+qW1rz2qM85SkvO3lBvrZCyEumoztjmgcUyRG9KorYf88y+vcp5mvH\n9Mz2cEREpIuk0jM2xN1XZ25IqVHPmBSicNhpDjvdyvQh4CIi+SRZz1hKHxSei1SMiYiISL7oig8K\nL3hBn8tWXn5mKU95yiucvCBfWyHkJaNiTCRH1W2NEA7r7q+ISNBpmlIkB0UizhW//phQszPtnAH0\n653xpfxERKQLdXadMRHJsDnPbmL+2w30riiiuVm/dIiIBJmmKVMU9Lls5eVO1r8XbeX+ZzZiBv/z\nvf4M6pf8d6Ygv5bKU57yspOlvMxSMSaSQ1ava+bn967FHc76Uh8OP7BHtockIiJppp4xkRzy28fW\n84e/bebTB3TnF+cNpLgoYXuBiIjkGa0zJpInwhHnkb9t5uTPVtCnp5r2RUSCQuuMdYGgz2UrLzey\niouMM0/svVOFWJBfS+UpT3nZyVJeZqkYExEREckiTVOKiIiIpJmmKUVykLvz0HObWLsxnO2hiIhI\nFmW8GDOzMWa22MyqzWxKgud/YGZvmNlrZvaime2f6TEmEvS5bOVlPuvpl7Yw+4kNTLrpI5o78bFH\nQX4tlac85WUnS3mZldFizMyKgNuAk4CDgLEJiq0H3f1gdz8UuAG4OZNjFMmEd5Y0ctsj6wE456t9\nKCnWEhYiIoUqoz1jZnYkcJW7nxzbvhxwd7+unePHAuPc/csJnlPPmOSlTXVhfvCLVXy0LszXjunJ\nRWP7ZXtIIiKSZrn02ZRDgQ/jtpcBR7Q+yMx+DFwClAKfz8zQRNIvEnGuvX8tH60Ls9/wMn58Rt9s\nD0lERLIs08VYooqwze0td/818GszOxO4Ehif6GTjx4+nqqoKgMrKSkaNGsXo0aOB7XPBXbU9a9as\ntJ5fecHJi+9DaP38sccexwFV3XjxxRf44kn9KCsdkta8TF+f8pSnvPTltc5UXm7ntTyura2lQ+6e\nsS/gSODZuO3LgSlJjjdgQzvPeSbNnTtXecrrsqzNdeGM5nUl5SlPednJC/K1FUJerG5JWO9kumes\nGHgHOAFYCbwKjHX3RXHH7OPu78UefxW40t0TTWV6JscuIiIisqtypmfM3cNmdj7wHNF3ct7t7ovM\nbDow392fBs43sy8ATcB64OxMjlFEREQkk4oyHejuz7r7fu6+r7tfG9t3VawQw90vcvdPuPun3P2E\n+Ltm2RQ/B6w85e1MVn1DJKN56aY85SkvO3lBvrZCyEsm48WYSCF58bV6vnvVCv67uCHbQxERkRyl\nz6YUSZNlq0P86NpV1DU4Pzq9km+c0DvbQxIRkSzRZ1OKZFhDU4SrZ6+hrsE59tAenPH5XtkekoiI\n5CgVYykK+ly28jqvpqaWCedN4+gTxvL5U6bw9uIahg0q4dJx/TFL38cdBfG1VJ7ylJfdLOVlloox\nkS5QU1PL2InXU900jrqep1I67Pssf/M+vj9mCxU99J+ZiIi0Tz1jIl1gwnnTqG4aR3Fp+bZ94VA9\nI8vmMPv2GVkcmYiI5AL1jImk2ZoNoR0KMYDi0nLWbAhlaUQiIpIvVIylKOhz2crrnAGVpYRD9QCs\nX/4yEL0zNqCyNK25ELzXUnnKU172s5SXWSrGRDrh1be28sQLm5k6+Vwaa2/dVpCFQ/U01t7K1Mnn\nZnmEIiKS69QzJrILQs3OXU9u4JG/b6aoCO64fAhFoRXMvPEu1mwIMaCylKmTz2XEiKosj1RERHJB\nsp4xFWMiO2n56hAz7lnLO0ubKCqCc77ShzNP7E1RUfqWrxARkfymBv4uEPS5bOWlZv7bW/nBtat4\nZ2kTg/sVc8slg/n2mD47FGL5em3KU57ycjsvyNdWCHnJlGR7ACL5ZPiQUoqLjGMP7c7k7/SnZ7l+\nnxERkc7RNKXITlq1tpnB/YrTuqq+iIgEi3rGRERERLJIPWNdIOhz2crb0aa6MA8+u5FIZOcL/ly/\nNuUpT3n5mRfkayuEvGTUMybSyhvvNTDz3rWsXh+mW5lxxud7Z3tIIiISYJqmFIkJR5wHn93EA89s\nJOJw4Igypp0zgCH99TuLiIh0TrJpSv0rIwJs3BLm6tlrWPBuI2bw7ZN6M/4rfSgpVpO+iIikl3rG\nUhT0uexCz6voUUSo2enXu4jrLxjEuadU7nIhlmvXpjzlKS8YeUG+tkLIS0Z3xkSAkmLjp98fQEmJ\n0a93cbaHIyIiBUQ9YyIiIiJppqUtROL8fX4dG7eEsz0MERERQMVYyoI+l10IefUNEWbet4af37uW\n6x5YS7rurBbCa6k85Skv83lBvrZCyEsm4z1jZjYGmEW0ELzb3a9r9fzFwLlACPgYOMfdP8z0OCUY\nampqmXnjXbz+5nvUR56iz4jTqey/B8ceWp7toYmIiAAZ7hkzsyKgGjgBWAHMB85098VxxxwH/Mvd\nG8zsh8Bodz8zwbnUMyZJ1dTUMnbi9XSrmkRxaTnhUD0fvnYzD/xmMkcfvm+2hyciIgUkl3rGjgDe\ndfcl7h4CHgZOiT/A3V9w94bY5ivA0AyPUQJi5o13bSvEAIpLy9nj0Iu5/777szwyERGR7TJdjA0F\n4qccl5G82Po+8Je0jihFQZ/LDmLemg2hbYXY+uUvA9GCbM2GUFpzg/haKk95yst+XpCvrRDyksl0\nMZbo9lzCuUYzGwccBtyQ1hFJ3gtHnH8sqOfa+9fu8MHeAypLCYfqdzw2VM+AytJMD1FERKRdme4Z\nOxK42t3HxLYvBzxBE/8XgFuAY919bTvn8rPPPpuqqioAKisrGTVqFKNHjwa2V7zaDu52fUOELSWf\n5okXNrPojZcA+O3Mr/GZg3owb948Vq5cxS33vEi3qklsWr2ASHMjPZpe4aE7L2PJktqsj1/b2ta2\ntrUd3O2Wx7W1tQDcf//97faMZboYKwbeIdrAvxJ4FRjr7ovijjkUeAQ4yd3fT3IuNfAXsIef28QD\nf95IQ1P0Z2C3ASWcelxPTj6qJz3Li7Yd1/JuyjUbQgyoLGXq5HMZMaIqK2MWEZHClTMN/O4eBs4H\nngPeAh5290VmNt3MvhI77HqgAnjEzF4zsycyOcb2xFe6yst+Xu+KIhqanMP2787PfzSQB67ejW+c\n0HuHQgxgxIgqZt8+gwsnnMzs22dkpBDLt9dSecpTXn7kBfnaCiEvmYyvM+buzwL7tdp3VdzjL2Z6\nTJK7wmGnOMEHdp9weDkH7tWNqt3U/yUiIvlNn00pOal2ZYjH521m/ttbue+nu1NWmvDOroiISF5I\nNk2Z8TtjIu0JR5x/LdzK4/O28J/FDdv2//edBo78RI8sjkxERCR9Mtozls+CPpedC3k3/G4d0367\nhv8sbqB7mfHVY3pyz5W7dUkhpr4O5SlPefmeF+RrK4S8ZHRnTDKq5d2Ni955nwMe+dsO72487lPl\nvPleA6eO7sWYo3rSq1y/K4iISPCpZ0wypqamlrETrqfbiO2fFdlYeysP3XkZI0ZUEYk4DhQXqT9M\nRESCJVnPmIoxSTt35+2aJn54wZUU7X7Oto8oguiK+CPL5jD79hlZHKGIiEh65cw6Y/ks6HPZ6cp7\n6LlNjPvpCi648SOWfdSUlc+KBPV1KE95ysv/vCBfWyHkJaOeMUmrpatCrFwbpn+fYsK7lREO1be5\nM6bPihQRkUKmaUrptM31ETZuCTNsUNui6oPlTWzcEuHgfbuxdMkSxk68nm5ViXvGREREgko9Y9Ll\nGpsivLywgb/Pr+PVt7ZyyL7duf6CQR1+nz4rUkRECpF6xrpA0OeyU83buCXMdQ+s5fTLl3PNXWv4\nx4KthMNQZNFFWzsyYkTmPysS1NehPOUpL//zgnxthZCXjHrGZKdU9CjilYVbqW9w9htexglHlHP8\nYRX071Oc7aGJiIjkJU1TSkLLVoeo7FlMzwQLr77y5lZ2H1TC8MFqvBcREUmFesakXfE9XL3LSzjy\n+DN548OBvLOkiQvP7Mspx/bK9hBFRETynnrGukAQ57JramoZO/F6qpvGUbvlU9TyXX5x/a9YsPAD\nenQz6rZG0pYdxNczG1nKU57yCicvyNdWCHnJqGcswCIRZ82GMMs/bmb5x80UGXzpcz23PT/zxru2\nLTMB0QVYRxx+CX223Mcj182kW5lqdRERkXTTNGUALV8d4so71rBiTTNNoe2v0dCBJfxu+u7btr/+\nnSls7HNem+/vs/F2Hn/wuoyMVUREpBAkm6bM6ztjE86blvZ1qjK9LlaivD333JOVa5tZEbvDtfzj\nZpavDtEYcm66cHCbc/TuWUztyuhHDPXtVcTQQaUMHVjCHoN3/OseUFnKuiatiC8iIpJNeT0PVd00\njtPGX8czz7/DwvcbWVTbSHM48d2yjVvCbK6PUN8QoSnkhCNOR3fWWvdUVTeNY+zE66mpqW1zbCTi\nNDZF2LI1wobNYT7e0MzKNc1E2ll7619vbeXF1+r5+/w6/t8rW3j6pS3c8fBCxk5om/dOdQ3fvWol\nU277mFt/v55Hn9/MKwsbeL26cYc7Xy16lRdx5xVDeOqmYTx63TBu/clgppzVn2+f1GeH46ZOPpfG\n2lsJh+pZv/zlbSviT518btLXpSsEuTcgyNemPOUpL3t5Qb62QshLJq/vjBWXltN75IWcP+UORhx+\nEQCPXTeUyl5t17w6e/pKNtW1bUhv7/gfXruK/3vmVwzYf8eeqm5Vk5h5413Mvn3GDsd/bfIy6hva\nFkZP3TSMih5t70r+7O41bY6vmX8Pw0e1zfvlr+5h5PDzKe9uDB1YwtCBpew+sIRhg0oobmd5r332\nKEv8RJwRI6p46M7LmHnjXSyqe5+RZW8yVR9NJCIiklF53TN2/I+WALD6zZsZ/bUphCNw04WDKO/e\n9obfd366gk11YcIRCIed5jC4w59uHJZwLa2v/uRDFr5wEyOOuKTNc4l6qr5+2TLqGyKUlhglxUZp\niVFaAr+9fAi9K9pWTDPuWUNTyGPHQ2mp8fC9M+k98sKU8kRERCR/BLZnDKI9TkcdXMFtlw5JetyD\n1+zeZl8k4ljClwXuvGI3Jm8oZ1kotZ6qx64birV3sgSmnTOgzb53/tmDavVwiYiIFJS87hnrbI9T\nUZG1W0DtNqCEGdMmptxTtTOFWHvUwxWMvCBfm/KUp7zs5QX52gohL5m8LsZGls3hoTT2OI0YEe2p\nGlk2h4q6JwKXJyIiItmX1z1j+Tp2ERERKSw59XFIZjbGzBabWbWZTUnw/DFm9h8zC5nZaZken4iI\niFgzd0MAAA9sSURBVEgmZbQYM7Mi4DbgJOAgYKyZ7d/qsCXA2cCDmRxbR4I+l628/MxSnvKUVzh5\nQb62QshLJtPvpjwCeNfdlwCY2cPAKcDilgPcfWnsOc1BioiISOBltGfMzE4HTnL3ibHtccAR7j4p\nwbH3Ak+5+2PtnEs9YyIiIpIXcmmdsUSD2OWKavz48VRVVQFQWVnJqFGjGD16NLD99qO2ta1tbWtb\n29rWdqa3Wx7X1tbSIXfP2BdwJPBs3PblwJR2jr0XOC3JuTyT5s6dqzzl5VyW8pSnvMLJC/K1FUJe\nrG5JWNMUdVyudan5wD5mtqeZlQFnAn9KcnznV1IVERERyWEZX2fMzMYAtxB9J+fd7n6tmU0H5rv7\n02b2aeBxoBJoAFa5+ycTnMczPXYRERGRXZGsZ0yLvoqIiIikWU4t+pqv4hvylKe8XMlSnvKUVzh5\nQb62QshLRsWYiIiISBZpmlJEREQkzTRNKSIiIpKjVIylKOhz2crLzyzlKU95hZMX5GsrhLxkVIyJ\niIiIZJF6xkRERETSTD1jIiIiIjlKxViKgj6Xrbz8zFKe8pRXOHlBvrZCyEtGxZiIiIhIFqlnTERE\nRCTN1DMmIiIikqNUjKUo6HPZysvPLOUpT3mFkxfkayuEvGRUjImIiIhkkXrGRERERNJMPWMiIiIi\nOUrFWIqCPpetvPzMUp7ylFc4eUG+tkLIS0bFmIiIiEgWqWdMREREJM3UMyYiIiKSo1SMpSjoc9nK\ny88s5SlPeYWTF+RrK4S8ZFSMiYiIiGSResZERERE0kw9YyIiIiI5KuPFmJmNMbPFZlZtZlMSPF9m\nZg+b2btm9rKZDc/0GBMJ+ly28vIzS3nKU17h5AX52gohL5mMFmNmVgTcBpwEHASMNbP9Wx32fWCd\nu+8LzAKuz+QY2/P6668rT3k5l6U85SmvcPKCfG2FkJdMpu+MHQG86+5L3D0EPAyc0uqYU4D7Y4//\nCP+/vXsPtquszzj+feAEDAjhKimmgFQRhYKihRTQoFAmakVGYYaLGqCXqaMlxVEEcQawtIKi4DjD\nH7UB2iAWiaigXCRcvBQTiJCEhBSxIZIQE0IkEoZLIfz6x/uezGJn33LOevc+l+czsyd7r/2u9ax1\nst73vGdd3sWxPVy/ljZs2OA85424LOc5z3njJ28sb9t4yGun152xNwIrK59X5WlNy0TEJmCDpN16\ns3pmZmZmvdXrzlizuwgab4lsLKMmZXpuxYoVznPeiMtynvOcN37yxvK2jYe8dno6tIWkqcBFETE9\nfz4PiIi4rFLmtlxmvqRtgd9HxBuaLKvvHTQzMzOzbrUa2mKgx+vxAPBmSfsCvwdOAU5tKHMLMAOY\nD5wM3N1sQa02yMzMzGw06WlnLCI2SfoM8FPSKdJZEbFM0sXAAxHxY2AWMFvSY8B6UofNzMzMbEwa\ntSPwm5mZmY0Fo24EfklflbRM0kJJ35e0c+W78/NgscskHV9T3kmSlkjaJOmwyvQBSddKWixpab7+\nrUhW/u4QSffl7xdJ2q5kXv5+H0kbJX12uFnt8iQdJ2lB3q4HJL2vZF7+rvZ9pWH5h+ZBix+SdL+k\nd9ed0STzH/OAyg9LurR0Xs78nKRXS9/x3K7e15zTdlDqmrOmSLpb0iP5/+zsknk5cxtJD0q6uQdZ\nkyTdmP/flko6onDeObm+L5b0nTrayIblz5K0VtLiyrRdJf1U0qOS7pA0qXBesXrQLK/yXe31vFVe\nqXasxc+z5+10SxExql7AccA2+f2lwFfy+7cDD5FOve4H/JZ85G+YeW8F3kK6du2wyvRTgevz+4nA\n48A+hbK2BRYBB+fPu5bctsr3c4AbgM/W9H/XavsOBSbn9wcBqwrnva3EvtKQfQdwfH7/AeCeOpff\nJO8Y0un/gfx5j5J5OWMKcHve93crnNW03tecsU3eF/YFJgALgQMLbtNk4B35/euBR0vm5ZxzgOuA\nm3uwf1wLnJnfDwA7F8zaG1gObJc/3wB8suaMo4F3AIsr0y4Dzs3vvwBcWjivWD1olpenF6nnLbav\nWDvWIq+n7XS716g7MhYRcyPi1fxxHmlHATgB+K+IeCUiVgCPkQaZHW7eoxHxGFsOuRHAjkp3fO4A\nvAQ8WyjreGBRRCzJ5Z6JvPcUykPSR4D/BZYON6dTXkQsiog1+f1SYHtJE0rlkQYWrn1fafAqMPhX\n8i7AkzUvv9GnSL8IXgGIiKcL5wFcAXy+Bznt6n2duhmUujYRsSYiFub3zwHL2HLcxdpImgJ8EPj3\nUhmVrJ2A90TENQC5rg2rfezCtqQ2eYDUJq+uc+ER8UvgmYbJ1UHK/wM4sWReyXrQYvugUD1vkVes\nHWuR1+t2uqVR1xlrcBZwa37fOKDskxRs2EhHjZ4n3RW6Arg8IkoN53sAgKTb8+m8or8AJe0AnAtc\nTPOx4UpmnwQ8lH8ZltKLfeUc4HJJT5Ae6XV+zctvdADwXknzJN1T+nC7pA8DKyPi4ZI5LZwF3FZg\nud0MSl2EpP1If7XPLxgz+Eu1FxcK7w88LemafFr03yRNLBUWEauBrwNPkOrzhoiYWyqv4g0RsTav\nwxpgzx5kDipVDzbrQz3vaTtG79vplno9tEVXJN0J7FWdRGpALoiIW3KZC4CXI+K7lTKNump0uslr\n4nDgFdKpht2BX0iam4+01J01ABwFvBt4EbhL0oKIuKfthg0972Lgioh4XtLgPF0ZYt7gvAcBXwH+\nqnDekPeVbrNJpxNmRsQPcwfzarZiu7Yy70ukfWSXiJgq6S+A75F+IZbK+yKv3Z5hd9q3st5fP9y8\nZqvQZFrxjouk15P+uJuZj5CVyPgQsDYiFko6hvJ/ZA0AhwGfjogFkq4EzgMuLBEmaRfSUap9gT8C\ncySdVmg/6bvC9WAwYyKpLau1nndQezvWwaeouZ0eqhHZGYuItj8MSTNIh9vfX5m8CvjTyucpdHmY\nulNeC6cBt+dDxusk/Teps7SiQNYq4GcR8QyApFtJDV3HztgQ844APibpq6Tr0zZJeiEiriqUN3gK\n5SbgE506tDXkDXlf6TZb0uyImJnLzZE0a6vXcuvy/oH08yMiHsgX2+4eEevrzpN0MOlau0VKvfUp\nwK8lHR4RT9WdV8ltVu/rtArYp/J5SPvF1sin1OYAsyPiRwWjjgJOkPRB0jWuO0n6z4j4ZKG8VaQj\nKgvy5zmka6pKOQ5YHhF/AJB0E3AkULoztlbSXhGxVtJkYMj7f7d6UA8G/RkF6nkHK6m5HetgRt3t\n9FCNutOUkqaTTqGdEBEvVb66GThF0naS3gS8Gbi/7vjK+yfIlUHSjsBU4H8KZd0BHCLpdbnxngY8\nUmPWa/Ii4r0RsX9E7A9cCfxrNx2xoeblO5B+DJwXEfNqztkij97sK09KmgYg6VjgNzUvv9EPgWNz\n3gHAhFINWEQsiYjJeR95E+kX7zsLNtDt6n2dNg9KrXQn3imkfaWkq4FHIuKbJUMi4osRsU+u06cA\ndxfsiJFP3a3M+yKkfbPuNqvqCWBqbiOV85YVyBFbtiVn5PczgLo71K/J60E92JzXo3re+PMs3Y41\n5vW6nW4t+nTnwFBfpIutfwc8mF9XVb47n3Q31DLyHRI15J1I6q2/QLo+7LY8fUfSIdQl+TXsOw5b\nZeXvTss5i6npDpp2eZUyF9axbR1+lhcAG/P/50P532HfRdPh51n7vtKQfSSwIG/Pr0iNWMl6MQGY\nDTycc6eVzGvIXk75uylb1vuac6aT7mp8jPTHQcltOgrYRLprc3C/n96D/69p9OZuykNJHdyFpKMd\nkwrnXZjr82LSxfQTal7+9aQjpS+ROn9nks4czM37zJ2kU2wl84rVg2Z5Dd/XWs9bbN9AqXasRV5P\n2+l2Lw/6amZmZtZHo+40pZmZmdlY4s6YmZmZWR+5M2ZmZmbWR+6MmZmZmfWRO2NmZmZmfeTOmJmZ\nmVkfuTNmZtaBpDMktX3WoaRvSer4VIyGefaU9JSkvYe3hmY2mrkzZmYjkqQ9JF0l6XFJL0paI+nO\nPFL2YJl78yNTTmuYd4akjZXP03K5wdfTku6SdGQX6zEB+Gfgoi5We/PAjfkh2dXMdZJukfTWzYUj\n1pEGKP1yF8s2szHKnTEzG6luIj3v9UzgLcCHgNuA3StlgvSEhUtyp4mG7xo/vw2YTBqFfh3wE0l7\ndFiPk4EXIuKXQ9iGwYefTyY9gHgi+dl7FdcCp+eHXZvZOOTOmJmNOPl5pUeTHkl0b0SsjIhfR8Q3\nIuJ7DcVvAF4HfLqLRa+LiKciYilwCTAJOKLDPKfS8IxKSdtIulzSHyStl3QFsG2TeV+KiMHMhcAV\nwIGSth8skNdlNfDRLtbfzMYgd8bMbCR6Lr9OqHZc2pT9MvAlSTt3KCsASTsAZ5GOlr3cYZ6jSc+v\nq/oc8DfA3wF/SeqInd42WNqJ9JDuxbHlQ57vJx2tM7NxyJ0xMxtxImITMAP4OLBB0n2Svibp8Baz\nfBtYD5zXZrECHs/Xkm0E/on0IOu7Ws6QjtBNIj1ovmomcFlEfD8ifpM/r2myiA9I2pgz/wi8h+ad\nttXAfm3W3czGMHfGzGxEiogfAHsDfw3cSjoCNU/SFh2u3Hm7ADi7zZ2JARwDvJN0hGo5cEaet5WJ\n+d8XByfko29/Asyr5Acwv8n8PwMOAQ4FDgfuBu6U9MaGci9UssxsnHFnzMxGrIj4v4i4KyIuiYij\ngVnARZIGmpSdAzxM+zsTV0TEbyPixlzuB00u/K9aT+rE7TrETXg+Ih6PiOURsQD4W2Bn4O8byu1G\nuqHAzMYhd8bMbDRZBgyQLthv5guk05sHdbGs2cAE2lz4HxEvA48Ab69Me5Z02nJqQ/FWp1AbvQrs\n0DDtYODBLuc3szHGnTEzG3Ek7ZbHATtd0p9L2k/SycDngbkR8Vyz+SLi58DtwGeaLbahbABXAudL\naneK8A7SRfxV3wTOlfQxSQdIupJ06rLR9pL2yq8DgW8BO1K5OzNnv4s0bIeZjUPujJnZSPQc8Cvg\nbOBeYAlpKIrrSNd7DWocSwzSRfwTmnzXrOzVpDshZ7ZZl28D0xvGAfs6cE3+bh6po3ddk3mPI12c\nvzqXexdwUkT8olLmROB3EXFfm3UwszFM6Y9DMzNrRdL1wNKI+JcCy54PfCMibqh72WY2OvjImJlZ\nZ+cCz9a9UEl7Aje6I2Y2vvnImJmZmVkf+ciYmZmZWR+5M2ZmZmbWR+6MmZmZmfWRO2NmZmZmfeTO\nmJmZmVkfuTNmZmZm1kfujJmZmZn10f8D159/5tlOv+AAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fce65883390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_leakyrelu_xavier\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.70  0.00   0.02  0.01  0.00   0.06   0.02  0.19\n",
      "BPSK   0.00  0.98   0.00  0.00  0.01   0.00   0.00  0.00\n",
      "CPFSK  0.01  0.00   0.98  0.00  0.00   0.00   0.00  0.00\n",
      "GFSK   0.00  0.00   0.01  0.99  0.00   0.00   0.00  0.00\n",
      "PAM4   0.00  0.03   0.00  0.00  0.97   0.00   0.00  0.00\n",
      "QAM16  0.13  0.01   0.00  0.00  0.00   0.41   0.40  0.05\n",
      "QAM64  0.04  0.00   0.00  0.00  0.00   0.46   0.50  0.01\n",
      "QPSK   0.07  0.01   0.00  0.00  0.00   0.01   0.00  0.91\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fce625b4240>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
